//*****************************************************************************
// JFab (http://code.google.com/p/jfab)
// Copyright (c) 2011 JFab.org
// Admin jfab@jeffreythompson.net
//
// See the file "LICENSE.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//*****************************************************************************

package org.jfab.core.io;

import org.jfab.core.factory.DefaultFactoryInjector;
import org.jfab.core.factory.FactoryInjector;
import org.jfab.core.factory.StringFactory;
import org.jfab.core.factory.TypeReferenceSupport;
import org.jfab.core.formatter.Formatter;
import org.jfab.core.formatter.SimpleFormatter;
import org.jfab.core.model.CGClass;
import org.jfab.core.model.CGConstructor;
import org.jfab.core.model.CGEnum;
import org.jfab.core.model.CGField;
import org.jfab.core.model.CGInterface;
import org.jfab.core.model.CGMethod;

/**
 * Provides a default I/O injector.
 */
public class DefaultIOInjector implements IOInjector
{
    /** Factory injector. */
    private final FactoryInjector _factoryInjector;

    /**
     * Construct this object.
     */
    public DefaultIOInjector()
    {
        this(new DefaultFactoryInjector());
    }

    /**
     * Construct this object with the given parameters.
     * 
     * @param factoryInjector Factory injector.
     */
    public DefaultIOInjector(final FactoryInjector factoryInjector)
    {
        _factoryInjector = factoryInjector;
    }

    @Override
    public BasicCodeGenerator injectBasicCodeGenerator()
    {
        return new DefaultBasicCodeGenerator();
    }

    @Override
    public CGWriter<CGClass> injectCGClassWriter()
    {
        return new CGClassWriter(injectTypeReferenceSupport(),
                injectStringFactory(), injectBasicCodeGenerator(),
                injectCGFieldWriter(), injectFormatter(),
                injectCGInitializationBlockWriter(),
                injectCGConstructorWriter(), injectCGMethodWriter());
    }

    @Override
    public CGWriter<CGEnum> injectCGEnumWriter()
    {
        return new CGEnumWriter(injectTypeReferenceSupport(),
                injectStringFactory(), injectBasicCodeGenerator(),
                injectCGFieldWriter(), injectFormatter(),
                injectCGInitializationBlockWriter(),
                injectCGConstructorWriter(), injectCGMethodWriter());
    }

    @Override
    public CGWriter<CGInterface> injectCGInterfaceWriter()
    {
        return new CGInterfaceWriter(injectTypeReferenceSupport(),
                injectStringFactory(), injectBasicCodeGenerator(),
                injectCGFieldWriter(), injectFormatter(),
                injectCGMethodDeclarationWriter());
    }

    @Override
    public Formatter injectFormatter()
    {
        return new SimpleFormatter();
    }

    @Override
    public WriterGroup injectWriterGroup()
    {
        return new WriterGroup(injectCGInterfaceWriter(),
                injectCGClassWriter(), injectCGEnumWriter());
    }

    /**
     * @return the factoryInjector
     */
    private FactoryInjector getFactoryInjector()
    {
        return _factoryInjector;
    }

    /**
     * @return a new code generator constructor writer.
     */
    private CGWriter<CGConstructor> injectCGConstructorWriter()
    {
        return new CGConstructorWriter(injectStringFactory(),
                injectBasicCodeGenerator());
    }

    /**
     * @return a new code generator field writer.
     */
    private CGWriter<CGField> injectCGFieldWriter()
    {
        return new CGFieldWriter(injectTypeReferenceSupport(),
                injectStringFactory(), injectBasicCodeGenerator());
    }

    /**
     * @return a new initialization block writer.
     */
    private CGInitializationBlockWriter injectCGInitializationBlockWriter()
    {
        return new CGInitializationBlockWriter(injectStringFactory(),
                injectBasicCodeGenerator());
    }

    /**
     * @return a new code generator method declaration writer.
     */
    private CGMethodDeclarationWriter injectCGMethodDeclarationWriter()
    {
        return new CGMethodDeclarationWriter(injectStringFactory(),
                injectBasicCodeGenerator());
    }

    /**
     * @return a new code generator method writer.
     */
    private CGWriter<CGMethod> injectCGMethodWriter()
    {
        return new CGMethodWriter(injectBasicCodeGenerator(),
                injectCGMethodDeclarationWriter());
    }

    /**
     * @return a new string factory.
     */
    private StringFactory injectStringFactory()
    {
        return getFactoryInjector().injectStringFactory();
    }

    /**
     * @return a new type reference support.
     */
    private TypeReferenceSupport injectTypeReferenceSupport()
    {
        return getFactoryInjector().injectTypeReferenceSupport();
    }
}
